﻿using System;
using System.Collections.Generic;
using System.Security.Cryptography;

namespace PhiStore.Experiments.Encryption
{
    class RSA
    {
        RSACryptoServiceProvider publicProvider;
        RSACryptoServiceProvider privateProvider;
       
        public RSA()
        {
            RSACryptoServiceProvider provider = new RSACryptoServiceProvider(1024);

            RSAParameters publicKey = provider.ExportParameters(false);
            RSAParameters privateKey = provider.ExportParameters(true);
            publicProvider = new RSACryptoServiceProvider();
            publicProvider.ImportParameters(publicKey);

            privateProvider = new RSACryptoServiceProvider();
            privateProvider.ImportParameters(privateKey);
        }

        public byte[] EncryptPublic(byte[] input)
        {
            List<byte> array = new List<byte>();
            int BlockLength = (publicProvider.KeySize / 8) - 42;
                //(publicProvider.KeySize / 8) - (SHA1.Create().ComputeHash(input).Length * 2 + 2);
            int blocksCount = input.Length / BlockLength;
            for (int i = 0; i <= blocksCount; i++)
            {
                int bytesCount = input.Length - BlockLength * i;
                if (bytesCount > BlockLength)
                {
                    bytesCount = BlockLength;
                }
                byte[] block = new byte[bytesCount];
                Buffer.BlockCopy(input, BlockLength * i, block, 0, block.Length);
                byte[] encryptedData = publicProvider.Encrypt(block, true);

                array.AddRange(encryptedData);
            }

            return array.ToArray();
        }

        public byte[] DecryptPrivate(byte[] input)
        {
            List<byte> array = new List<byte>();
            int keySize = privateProvider.KeySize / 8;
            int blocksCount = input.Length / keySize;
            for (int i = 0; i < blocksCount; i++)
            {
                int bytesCount = input.Length - keySize * i;
                if (bytesCount > keySize)
                {
                    bytesCount = keySize;
                }
                byte[] block = new byte[bytesCount];
                Buffer.BlockCopy(input, keySize * i, block, 0, block.Length);
                byte[] decryptedData = privateProvider.Decrypt(block, true);
                array.AddRange(decryptedData);
            }
            return array.ToArray();
        }
    }
}
